#include <p18f8520.h>
#include "EEPROM.h"

#define HIBYTE(value) ((unsigned char)(((unsigned int)(value)>>8)&0xFF))
#define LOBYTE(value) ((unsigned char)(value))

/*******************************************************************************
*
*	FUNCTION:		read_EEPROM()
*
*	PURPOSE:		Reads a byte of data from EEPROM.
*
*	CALLED FROM:
*
*	PARAMETERS:		address
*
*	RETURNS:		 data
*
*	COMMENTS:
*
*******************************************************************************/
unsigned char read_EEPROM(unsigned int address)
{
	// EEPROM operation (as opposed to a flash memory operation)
    EECON1bits.EEPGD = 0; 

	// EEPROM Address
    EEADR = LOBYTE(address);
	EEADRH = HIBYTE(address);

    // execute the read
	EECON1bits.RD = 1;

	// return the data    
    return(EEDATA);
}
    
/*******************************************************************************
*
*	FUNCTION:		write_EEPROM()
*
*	PURPOSE:		Writes data to EEPROM
*
*	CALLED FROM:
*
*	PARAMETERS:		data,  address
*
*	RETURNS:		nothing
*
*	COMMENTS:		it will take about two milliseconds
*					to execute the EEPROM write.
*
*******************************************************************************/
void write_EEPROM(unsigned char data,unsigned int address)
{
    unsigned char temp_GIEH;
	unsigned char temp_GIEL;

		// save the state of the interrupt enable bits
	    temp_GIEH = INTCONbits.GIEH;
		temp_GIEL = INTCONbits.GIEL;
	
		// EEPROM operation (as opposed to a flash memory operation)
	    EECON1bits.EEPGD = 0;
	
		// Only do a write
	    EECON1bits.FREE = 0;  
	
	    // make sure the EEPROM write done flag is reset
		PIR2bits.EEIF = 0;
	
		// set EEPROM address
	    EEADR = LOBYTE(address);
		EEADRH = HIBYTE(address);
	
		// set EEPROM data to write
	    EEDATA = data;

		// enable EEPROM writes
	    EECON1bits.WREN = 1;
	
	    // disable Interrupts
		INTCONbits.GIEH = 0;
		INTCONbits.GIEL = 0;
	    
	    // pre-write sequence
	    EECON2 = 0x55;
	    EECON2 = 0xAA;
	    
		// execute the write
		EECON1bits.WR = 1;

		// set GIEH to its original state
	    INTCONbits.GIEH = temp_GIEH;
	
		// set GIEL to its original state
	    INTCONbits.GIEL = temp_GIEL;
	
	    // wait for the write to complete
		while(PIR2bits.EEIF == 0);
	
		// clear the write completion interrupt flag
	    PIR2bits.EEIF = 0;
	
	    // disable EEPROM writes
		EECON1bits.WREN = 0;

}
